package com.kla.power.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.kla.power.entity.InverterAmountStatisticsDayEntity;
import com.kla.power.entity.StationEntity;
import com.kla.power.mapper.InverterAmountStatisticsDayMapper;
import com.kla.power.service.IInverterAmountStatisticsDayService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.kla.power.util.CommonUtil;
import com.kla.power.util.ResultBody;
import com.kla.power.util.StateEnum;
import com.kla.power.util.StateException;
import com.kla.power.vo.YearReportVo;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.time.LocalDate;
import java.time.ZoneId;
import java.util.*;
import java.util.stream.Collectors;

/**
 * <p>
 * 逆变器电量统计，每日凌晨更新昨日发电量，用于显示逆变器详情页 服务实现类
 * </p>
 * @author WuZH
 * @since 2024-06-02
 */
@Service
public class InverterAmountStatisticsDayServiceImpl extends ServiceImpl<InverterAmountStatisticsDayMapper, InverterAmountStatisticsDayEntity> implements IInverterAmountStatisticsDayService {

    @Resource
    private InverterAmountStatisticsDayMapper inverterAmountStatisticsDayMapper;

    @Override
    public InverterAmountStatisticsDayEntity saveSingle (InverterAmountStatisticsDayEntity inverterAmountStatisticsDayEntity) {
        if ( inverterAmountStatisticsDayEntity == null ) {
            throw new StateException ( StateEnum.REQUEST_PARAM_EXCE );
        }
        if ( StringUtils.isBlank ( inverterAmountStatisticsDayEntity.getId () ) ) {
            throw new StateException ( StateEnum.PRIMARY_NULL_EXCE );
        }
        inverterAmountStatisticsDayEntity.setCreateTime ( new Date () );
        int insert = baseMapper.insert ( inverterAmountStatisticsDayEntity );
        if ( insert == 0 ) {
            throw new StateException ( StateEnum.INSERT_EXCE );
        }
        return inverterAmountStatisticsDayEntity;
    }

    /**
     * 查询某逆变器在规定时间内的发电量数据
     * @param inverterAmountStatisticsDayEntity
     * @return
     */
    @Override
    public List<InverterAmountStatisticsDayEntity> queryHistoryList (InverterAmountStatisticsDayEntity inverterAmountStatisticsDayEntity) {
        List<InverterAmountStatisticsDayEntity> inverterAmountStatisticsDayEntities = inverterAmountStatisticsDayMapper.queryHistoryList ( inverterAmountStatisticsDayEntity );
        return inverterAmountStatisticsDayEntities;
    }

    @Override
    public List<InverterAmountStatisticsDayEntity> queryAllStationAmountList (StationEntity stationEntity) {
        List<InverterAmountStatisticsDayEntity> inverterAmountStatisticsDayEntities = inverterAmountStatisticsDayMapper.queryAllStationAmountList ( stationEntity );
        return inverterAmountStatisticsDayEntities;
    }

    @Override
    public ResultBody queryDay (InverterAmountStatisticsDayEntity inverterAmountStatisticsDayEntity) {
        int page = inverterAmountStatisticsDayEntity.getPage ();
        inverterAmountStatisticsDayEntity.setPage ( ( inverterAmountStatisticsDayEntity.getPage () - 1 ) * inverterAmountStatisticsDayEntity.getLimit () );
        List<InverterAmountStatisticsDayEntity> inverterAmountStatisticsDayEntities = inverterAmountStatisticsDayMapper.queryDay ( inverterAmountStatisticsDayEntity );
        for ( InverterAmountStatisticsDayEntity amountStatisticsDayEntity : inverterAmountStatisticsDayEntities ) {
            List<InverterAmountStatisticsDayEntity> list = this.list ( new LambdaQueryWrapper<InverterAmountStatisticsDayEntity> ().eq ( InverterAmountStatisticsDayEntity :: getInverterSn, amountStatisticsDayEntity.getInverterSn () ) );
            if ( list != null && list.size () > 0 ) {
                double sum = list.stream ().mapToDouble ( d -> Double.parseDouble ( StringUtils.isBlank ( d.getYesterdayPower () ) ? "0" : d.getYesterdayPower () ) ).sum ();
                amountStatisticsDayEntity.setSum ( sum );
            }
        }
        Integer count = inverterAmountStatisticsDayMapper.queryDayCount ( inverterAmountStatisticsDayEntity );
        return ResultBody.success ( page, inverterAmountStatisticsDayEntity.getLimit (), count, inverterAmountStatisticsDayEntities );
    }

    /**
     * 组装1号到今天的数据
     * @param inverterAmountStatisticsDayEntity
     * @return
     */
    @Override
    public List<InverterAmountStatisticsDayEntity> queryMonth (InverterAmountStatisticsDayEntity inverterAmountStatisticsDayEntity) {
        //这个月1号到今天的日期查数据
        Date month = inverterAmountStatisticsDayEntity.getMonthDate ();
        inverterAmountStatisticsDayEntity.setStartTime ( month );
        // 使用 Calendar 来获取月份的最后一天，然后转换为 LocalDate
        Calendar calendar = Calendar.getInstance ();
        calendar.setTime ( month );
        calendar.set ( Calendar.DAY_OF_MONTH, calendar.getActualMaximum ( Calendar.DAY_OF_MONTH ) );
        LocalDate localDate = calendar.getTime ().toInstant ().atZone ( ZoneId.systemDefault () ).toLocalDate ();
        inverterAmountStatisticsDayEntity.setEndTime ( Date.from ( localDate.atStartOfDay ( ZoneId.systemDefault () ).toInstant () ) );
        List<InverterAmountStatisticsDayEntity> inverterAmountStatisticsDayEntities = inverterAmountStatisticsDayMapper.queryMonth ( inverterAmountStatisticsDayEntity );
        //组装每台逆变器每一天的发电数据
        Map<String, List<InverterAmountStatisticsDayEntity>> collect = inverterAmountStatisticsDayEntities.stream ().collect ( Collectors.groupingBy ( InverterAmountStatisticsDayEntity :: getInverterSn ) );
        List<InverterAmountStatisticsDayEntity> list = new ArrayList<> ();
        for ( Map.Entry<String, List<InverterAmountStatisticsDayEntity>> e : collect.entrySet () ) {
            InverterAmountStatisticsDayEntity data = new InverterAmountStatisticsDayEntity ();
            String key = e.getKey (); // 逆变器SN
            List<InverterAmountStatisticsDayEntity> value = e.getValue (); // 发电量数据集
            //按照日期从小到大排序
            value.sort ( Comparator.comparing ( InverterAmountStatisticsDayEntity :: getCollectorTime ) );
            Map<String, List<InverterAmountStatisticsDayEntity>> days = value.stream ().collect ( Collectors.groupingBy ( InverterAmountStatisticsDayEntity :: getDay ) );
            Map<String, Double> map = new HashMap<> ();
            for ( Map.Entry<String, List<InverterAmountStatisticsDayEntity>> entry : days.entrySet () ) {
                List<InverterAmountStatisticsDayEntity> sub = entry.getValue ();//这个月每天的发电量
                if ( sub != null && sub.size () > 0 ) {
                    double sum = sub.stream ().mapToDouble ( d -> Double.parseDouble ( StringUtils.isBlank ( d.getYesterdayPower () ) ? "0" : d.getYesterdayPower () ) ).sum ();
                    map.put ( entry.getKey (), sum );
                }
            }
            // 检查并填充缺少的天数，设置默认值为0，每个月都统一按照31天计算
            for ( int day = 1; day <= 31; day++ ) {
                if ( ! map.containsKey ( String.valueOf ( day ) ) ) {
                    map.put ( String.valueOf ( day ), 0.0 );
                }
            }
            //把map的转为List
            List<Map.Entry<String, Double>> lista = new ArrayList<> ( map.entrySet () );
            // 定义比较器并排序
            Collections.sort ( lista, new Comparator<Map.Entry<String, Double>> () {
                public int compare (Map.Entry<String, Double> o1, Map.Entry<String, Double> o2) {
                    return Integer.compare ( Integer.parseInt ( o1.getKey () ), Integer.parseInt ( o2.getKey () ) );
                }
            } );
            // 如果需要将排序后的结果放入新的LinkedHashMap中以保持顺序
            Map<String, Double> sortedMap = new LinkedHashMap<> ();
            for ( Map.Entry<String, Double> entry : lista ) {
                sortedMap.put ( entry.getKey (), entry.getValue () );
            }
            List<Double> powers = new ArrayList<> ( sortedMap.values () );
            data.setStationName ( value.get ( 0 ).getStationName () );
            data.setDeviceTitle ( value.get ( 0 ).getDeviceTitle () );
            data.setPower ( value.get ( 0 ).getPower () );
            data.setPowers ( powers );
            data.setDeviceSn ( key );
            data.setInverterSn ( key );
            list.add ( data );
        }
        return list;
    }

    @Override
    public List<InverterAmountStatisticsDayEntity> queryYear (InverterAmountStatisticsDayEntity inverterAmountStatisticsDayEntity) {
        List<InverterAmountStatisticsDayEntity> inverterAmountStatisticsDayEntities = inverterAmountStatisticsDayMapper.queryYear ( inverterAmountStatisticsDayEntity );
        //拿到所有逆变器的一整年的数据，要根据逆变器分组，并分别求出每个月的逆变器发电量之和
        Map<String, List<InverterAmountStatisticsDayEntity>> collect = inverterAmountStatisticsDayEntities.stream ().collect ( Collectors.groupingBy ( InverterAmountStatisticsDayEntity :: getInverterSn ) );
        List<InverterAmountStatisticsDayEntity> list = new ArrayList<> ();
        for ( Map.Entry<String, List<InverterAmountStatisticsDayEntity>> e : collect.entrySet () ) {
            InverterAmountStatisticsDayEntity data = new InverterAmountStatisticsDayEntity ();
            String sn = e.getKey ();//逆变器SN
            data.setDeviceSn ( sn );
            data.setInverterSn ( sn );
            List<InverterAmountStatisticsDayEntity> value = e.getValue ();//每台逆变器一年的数据，要按月份再次分组
            value.sort ( Comparator.comparing ( InverterAmountStatisticsDayEntity :: getCollectorTime ) );
            Map<String, List<InverterAmountStatisticsDayEntity>> months = value.stream ().collect ( Collectors.groupingBy ( InverterAmountStatisticsDayEntity :: getMonth ) );
            Map<String, Double> map = new HashMap<> ();
            for ( Map.Entry<String, List<InverterAmountStatisticsDayEntity>> entry : months.entrySet () ) {
                List<InverterAmountStatisticsDayEntity> sub = entry.getValue ();//每个月的发电量
                if ( sub != null && sub.size () > 0 ) {
                    double sum = sub.stream ().mapToDouble ( d -> Double.parseDouble ( StringUtils.isBlank ( d.getYesterdayPower () ) ? "0" : d.getYesterdayPower () ) ).sum ();
                    map.put ( entry.getKey (), sum );
                }
            }
            // 检查并填充缺少的月份，设置默认值为0
            for ( int month = 1; month <= 12; month++ ) {
                if ( ! map.containsKey ( String.valueOf ( month ) ) ) {
                    map.put ( String.valueOf ( month ), 0.0 );
                }
            }
            //把map的转为List
            List<Map.Entry<String, Double>> lista = new ArrayList<> ( map.entrySet () );
            // 定义比较器并排序
            Collections.sort ( lista, new Comparator<Map.Entry<String, Double>> () {
                public int compare (Map.Entry<String, Double> o1, Map.Entry<String, Double> o2) {
                    return Integer.compare ( Integer.parseInt ( o1.getKey () ), Integer.parseInt ( o2.getKey () ) );
                }
            } );
            // 如果需要将排序后的结果放入新的LinkedHashMap中以保持顺序
            Map<String, Double> sortedMap = new LinkedHashMap<> ();
            for ( Map.Entry<String, Double> entry : lista ) {
                sortedMap.put ( entry.getKey (), entry.getValue () );
            }
            List<Double> powers = new ArrayList<> ( sortedMap.values () );
            data.setStationName ( value.get ( 0 ).getStationName () );
            data.setDeviceTitle ( value.get ( 0 ).getDeviceTitle () );
            data.setPower ( value.get ( 0 ).getPower () );
            data.setPowers ( powers );
            list.add ( data );
        }
        return list;
    }

    @Override
    public List<InverterAmountStatisticsDayEntity> downDay (InverterAmountStatisticsDayEntity inverterAmountStatisticsDayEntity) {
        List<InverterAmountStatisticsDayEntity> inverterAmountStatisticsDayEntities = inverterAmountStatisticsDayMapper.downDay ( inverterAmountStatisticsDayEntity );
        for ( InverterAmountStatisticsDayEntity amountStatisticsDayEntity : inverterAmountStatisticsDayEntities ) {
//            List<InverterAmountStatisticsDayEntity> list = this.list ( new LambdaQueryWrapper<InverterAmountStatisticsDayEntity> ().eq ( InverterAmountStatisticsDayEntity :: getInverterSn, amountStatisticsDayEntity.getInverterSn () ) );
//            if ( list != null && list.size () > 0 ) {
//                double sum = list.stream ().mapToDouble ( d -> Double.parseDouble ( StringUtils.isBlank ( d.getYesterdayPower () ) ? "0" : d.getYesterdayPower () ) ).sum ();
//                amountStatisticsDayEntity.setSum ( sum );
//            }
        }
        return inverterAmountStatisticsDayEntities;
    }

    @Override
    public List<InverterAmountStatisticsDayEntity> downMonth (InverterAmountStatisticsDayEntity inverterAmountStatisticsDayEntity) {
        return null;
    }

    @Override
    public List<InverterAmountStatisticsDayEntity> downYear (InverterAmountStatisticsDayEntity inverterAmountStatisticsDayEntity) {
        return null;
    }

}
